#include <string.h>
#include <iostream>

using std::cout;
using std::endl;

class Base
{
public:
    Base(const char * base)
    : _base(new char[strlen(base) + 1]())
    {   
        cout << "Base(const char*)" << endl;
        strcpy(_base, base);
    }

    //析构函数是一个特殊的成员函数，一个类只有一个
    //因此正好可以利用动态多态的特性
    //一旦将基类析构函数设置为虚函数之后，派生类析构函数
    //会自动成为虚函数
    //
    //一般情况下， 都应该将析构函数设置为虚函数
    virtual
    ~Base()
    {
        cout << "~Base()" << endl;
        if(_base) {
            delete [] _base;
            _base = nullptr;
        }
    }

    void print() const
    {   cout << "_base:" << _base << endl;}

private:
    char * _base;
};

class Derived
: public Base
{
public:
    Derived(const char * base, const char * derived)
    : Base(base)
    , _derived(new char[strlen(derived) + 1]())
    {
        strcpy(_derived, derived);
        cout << "Derived()" << endl;
    }

    void display() const 
    {   cout << "_derived:" << _derived << endl;}
    
    //基类析构函数设置为虚函数之后，派生类型析构函数自动成为虚函数
    //即使不加virtual关键字，依然是虚函数
    ~Derived()
    {
        cout << "~Derived()" << endl;
        if(_derived) {
            delete [] _derived;
            _derived = nullptr;
        }
    }

private:
    char * _derived;
};

int main()
{
    Base * pbase = new Derived("hello", "world");
    pbase->print();

    //delete表达式工作步骤：1. 调用析构函数 2.调用operator delete库函数
    //希望通过基类指针能够调用到派生类析构函数
    delete pbase;//只调用了基类的析构函数
    return 0;
}

